#include <iostream>
#include <stdlib.h>
#include <map>
#include <string>
#include <functional>

#include "xgit/executor.h"
#include "xgit/exec_init.h"
#include "xgit/exec_sync.h"
#define XGIT_VER "0.1.0"

using namespace xgit;
using CmdMap = std::map<std::string, ExecutorSp>;

using OnCmd = std::function<bool(int argc, const char* const argv[])>;
using CmdMap2 = std::map<std::string, OnCmd>;

static bool GitCmdIsExist() {
    return system("git --version") == 0;
}

static void ShowUsage(const CmdMap2& cmd_map) {
    printf("usage: xgit [--version][--help | -h]\n");
}


static void CmdMapInit(CmdMap& cmd_map, CmdMap2& cmd_map2) {
    cmd_map["init"] = std::make_shared<ExecInit>();
    cmd_map["sync"] = std::make_shared<ExecSync>();

    cmd_map2["init"] = [](int argc, const char* const argv[]) -> bool {
        ExecInit init;
        return init.exec(argc, argv);
    };

    cmd_map2["sync"] = [](int argc, const char* const argv[]) -> bool {
        ExecSync sync;
        return sync.exec(argc, argv);
    };

    cmd_map2["--help"] = [&cmd_map2](int argc, const char* const argv[]) -> bool {
        static_cast<void>(argc);
        static_cast<void>(argv);
        ShowUsage(cmd_map2);
        return true;
    };

    cmd_map2["-h"] = [&cmd_map2](int argc, const char* const argv[]) -> bool {
        static_cast<void>(argc);
        static_cast<void>(argv);
        ShowUsage(cmd_map2);
        return true;
    };

    cmd_map2["--version"] = [&cmd_map2](int argc, const char* const argv[]) -> bool {
        static_cast<void>(argc);
        static_cast<void>(argv);
        printf("xgit version: %s\n" , XGIT_VER);
        return true;
    };
}

static OnCmd ParseArg(CmdMap2& cmd_map, int argc, char* argv[]) {
    if (argc >= 2) {
        std::string cmd = argv[1];
        std::cout << "cmd: " << cmd << std::endl;
        auto on_cmd = cmd_map.find(cmd);
        if (on_cmd != cmd_map.end()) {
            return on_cmd->second;
        }
    }
    return nullptr;
}

int main(int argc, char* argv[]) {
    CmdMap cmd_map;
    CmdMap2 cmd_map2;
    CmdMapInit(cmd_map, cmd_map2);
    std::cout <<"hello xgit " << std::endl;
    std::cout << "git cmd is exist: " << GitCmdIsExist() << std::endl;
    if (!GitCmdIsExist()) {
        return -1;
    }

    auto on_cmd = ParseArg(cmd_map2, argc, argv);

    if (!on_cmd) {
        ShowUsage(cmd_map2);
        return -1;
    } 
    argc -= 1;
    argv += 1;

    return on_cmd(argc, argv) ? 0 : -1;
}